<?php
namespace App\Library\Impl;
use App\Exceptions\BusinessException;
use App\Library\ScheduleLibraryInterFace;
use App\Models\Address;
use App\Models\DawnOss;
use App\Models\Push;
use App\Models\ZhjyRepot;
use App\Pojo\Response;
use App\Services\PushServiceInterFace;
use App\Services\ZhjyServiceInterface;
use Illuminate\Support\Facades\Log;
use App\Models\ScheduleTask;
use Illuminate\Support\Facades\Auth;
use App\Models\DawnZhjyUser;
use Illuminate\Support\Facades\Http;
use App\Constant\ApiUrl;
use App\Utils\Utils;
use App\Models\DawnTaskSettings;
use App\Models\LogTaskSettings;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\UploadedFile;

final class ScheduleLibraryImpl implements ScheduleLibraryInterFace {
   
   protected $zhjyService;
   protected $apiUrl;
   private $headers = [
      'Content-Type' => 'application/json',
      'User-Agent' => ''
  ];
  protected $pushService;
   public function __construct(ZhjyServiceInterface $zhjyServiceInterface, ApiUrl $apiUrl, PushServiceInterFace $pushServiceInterFace)
   {
      $this->zhjyService = $zhjyServiceInterface;
      $this->headers['User-Agent'] = Utils::generateRandomHeaders()['User-Agent'];
      $this->apiUrl = $apiUrl;
      $this->pushService = $pushServiceInterFace;
   }

   public function saveTask($schedule) {
      $scheduleTask = [];
      $scheduleTask["user_id"] = Auth::id();
      $scheduleTask["name"] = $schedule["name"];
      $scheduleTask["time_type"] = $schedule["time_type"];
      $scheduleTask["cron_expression"] = $schedule["cron"];
      $scheduleTask["time_type"] = $schedule["time_type"];
         if ($schedule['time_type'] === 'delay_time') {
             $scheduleTask["delay_time"] = $schedule["delay"];
         } else if ($schedule['time_type'] === 'jitter_time') {
             $scheduleTask["jitter_time"] = $schedule["jitter_time"];
         } else {
             Log::info($scheduleTask);
         }
         ScheduleTask::create($scheduleTask);
   }

   public function dailyCheckInTask($task){
      Log::info('=================dailyCheckInTask======================');
      $maxAttempts = 3;
      $attemptCount = 0;
      while ($attemptCount < $maxAttempts) {
         try {
            $this->zhjyloginTask($task);
            break; // 如果成功就跳出循环
         } catch (\Exception $e) {
            $attemptCount++;
            Log::error('智慧教育登录失败(第' . $attemptCount . '次):' . $e->getMessage());
            
            if ($attemptCount >= $maxAttempts) {
               throw new BusinessException('智慧教育登录失败:已重试' . $maxAttempts . '次');
            }
            
            // 等待一秒后重试
            sleep(3);
         }
      }
      Log::info('================dailyCheckInTask=======================');
   }

   public function logTask($task){
      Log::info('=================logTask======================');

      $maxAttempts = 3;
      $attemptCount = 0;
      while ($attemptCount < $maxAttempts) {
         try {
            $this->zhjyLogTask($task);
            break; // 如果成功就跳出循环
         } catch (\Exception $e) {
            $attemptCount++;
            Log::error('智慧教育日志上传失败(第' . $attemptCount . '次):' . $e->getMessage());
            
            if ($attemptCount >= $maxAttempts) {
               Log::error('智慧教育日志上传失败:已重试' . $maxAttempts . '次');
               break; // 达到最大重试次数后退出
            }
            // 等待3秒后重试
            sleep(3);
         }
      }
      Log::info('================logTask=======================');
   }

   public function getTaskList($credentials){
      return ScheduleTask::where('user_id', Auth::id())
      ->where('is_active', '!=', 2)
      ->orderBy('created_at', 'desc')
      ->paginate($credentials['per_page'], ['*'], 'page', $credentials['page']);
   }


   public function updataTask($id){
      $task = ScheduleTask::findOrFail($id);
      if($task->is_active){
         throw new BusinessException('删除失败，任务已启用');
      } 
      $task->is_active = 2; // 2表示任务已删除
      $task->save();
   }

   public function toggleTaskStatus($id, $isActive){
      $boolValue = filter_var($isActive, FILTER_VALIDATE_BOOLEAN);
      ScheduleTask::where('id', $id)->update(['is_active' => $boolValue]);
      return ScheduleTask::findOrFail($id);
   }


   /**
    * 智慧教育登录
    */
    public function zhjyloginTask($task)
    {
      $user = DawnZhjyUser::where('dawn_id', $task->user_id)->first();
      $loginBody = [
               "appLogin"=>"true",
               "loginAccount"=> $user->dawn_zhjyUser,
               "password"=> $user->dawn_zhjyPassword,
               "appUserId"=>"",
               "loginUserType"=>$user->dawn_zhjyidEntity,
               "enrollmentYear"=>$user->dawn_zhjyEnrollmentYear
         ];
     $response = Http::withHeaders($this->headers)->post($this->apiUrl->getLoginUrl(), $loginBody);
     if ($response->successful()) {
         // 获取响应的 JSON 数据
         $message = $response->json();
         if($message['code'] == 500){
            throw new BusinessException($task->name.'智慧教育,用户名或密码不正确');
         }
         $data = $response->json()['data'];
          // 获取实习Id
          $token = 'Bearer '.$data['token'];
          $userId = $data['userId'];
          $nickName = $data['nickName'];
          $autonomyPlanId = $this->zhjyService->getStudentPlanId($token);
          Log::info('获取实习Id:');
          Log::info($autonomyPlanId);
         /**
          * 获取自动打卡的任务配置、打卡图片数量、打卡地址随机开关、打卡反馈开关等配置
          */
          $taskSettings = DawnTaskSettings::where('user_id', $task->user_id)->first();
          if($taskSettings){
            $taskSettings = $taskSettings->toArray();
            Log::info($taskSettings);
            $settings_id = $taskSettings['id'];
            $settings_user_id = $taskSettings['user_id'];
            $settings_image_count = $taskSettings['image_count'];
            $settings_random_location = $taskSettings['random_location'];
            $settings_default_images = $taskSettings['default_images'];
            $settings_feedback_enabled = $taskSettings['feedback_enabled'];
            $settings_created_at = $taskSettings['created_at'];
            $settings_updated_at = $taskSettings['updated_at'];
            $settings_deleted_at = $taskSettings['deleted_at'];

            if($settings_random_location == true){
               // 获取随机地址           
               $address = Address::where('user_id', $task->user_id)
                  ->inRandomOrder() // 随机获取一条
                  ->first();
            }else{
               // 获取最新的打卡地址
               $address =Address::where('user_id', $task->user_id)
                  ->orderBy('updated_at', 'desc')  // 使用 updated_at 或其他时间字段
                  ->first();
            }
            // 确定上传图片数据量
            $count = DawnOss::where('user_id', $task->user_id)
                        ->where("status", 1)
                        ->get()
                        ->count();

            $imageids = [];
            $delHash = [];
            for($i = 0; $i < $settings_image_count; $i++){
               if ($count < $settings_image_count){
                  // 如果图片数量不足，则随机获取一条
                  $ossPath = DawnOss::where('user_id', $task->user_id)
                  ->inRandomOrder() // 所有数据随机获取一条
                  ->first();
               }else{
                  $ossPath = DawnOss::where('user_id', $task->user_id)
                  ->inRandomOrder() // 随机获取一条
                  ->where("status", 1) // 随机获取一条
                  ->first();
               }
               $path = storage_path('app/public/' . ltrim($ossPath['file_path'], '/'));
               // $path =asset('storage/' . $ossPath['file_path']);
               $file = new UploadedFile($path, $ossPath['file_name']);
               $currentHeader = [
                  "Authorization" => $token,
               ];
               $result = $this->zhjyService->uploadFile($currentHeader, $file);
               if($result['code'] == 500){
                  Log::error('上传图片失败:'.$result['message']);
                  continue; // 跳过当前循环
               }
               $id = $result['id'];
               $url = $result['url'];
               $fileName = $result['url'];
               $imageids[] = $id;
               $delHash[] = $ossPath['file_hash'];
            }
               $fileIdsStr = implode(',', $imageids);

            // 判断是否需要打卡反馈
            if($settings_feedback_enabled == true){
               if (is_null($address->describe)) {
                  $describe = '';
               }else{
                  $describe = $address->describe;
               }
            }else{
               $describe = '';
            }
            $addBody = [
               "autonomyId"=> $autonomyPlanId,
               "userId"=> $userId,
               "nickName"=> $nickName,
               "clockAddress"=> $address->address,
               "fileId"=> $fileIdsStr,
               "clockTime"=> Utils::getFormatted_datetime_now(),
               "clockType"=> '签到',
               "clockContent"=> $describe
           ];
           $mergedHeaders = array_merge($this->headers, $currentHeader);
           $response = Http::withHeaders($mergedHeaders)
               ->post($this->apiUrl->getDawnUrl(), $addBody);
            $push = Push::where('user_id', $task->user_id)->first();
            if ($response->successful()) {
               $data = $response->json();
               if($data['code'] == 500){
                Log::info("打卡失败");
                Log::info($data);
                if(!is_null($push)){
                  $sendMsg = [
                     "token"=> $push->token,
                     "msg"=> '实习打卡提交失败-'."地址: ".$addBody['clockAddress'].'时间: '.Utils::getFormatted_datetime_now(),
                 ];
                  $this->pushService->sendMsg($sendMsg);
               }
               }
               if($data['code'] == 200){
                   Log::info("打卡成功");
                   Log::info($data);
                   if(!is_null($push)){
                     $sendMsg = [
                        "token"=> $push->token,
                        "msg"=> '实习打卡提交成功-'."地址: ".$addBody['clockAddress'].'时间: '.Utils::getFormatted_datetime_now(),
                    ];
                     $this->pushService->sendMsg($sendMsg);
                  }
                  foreach ($delHash as $hash) {
                     DawnOss::where('file_hash', $hash)->update(['status' => 0]);
                     Log::info('删除图片:'.$hash);
                  }
                }
            }else{
               throw new BusinessException($task->name.'平台服务器异常');
            }
          }else{
            throw new BusinessException($task->name.'智慧教育,请先配置打卡设置');
          }
          Log::info('获取自动打卡的任务配置、打卡图片数量、打卡地址随机开关、打卡反馈开关等配置');

      } else {

         throw new BusinessException($task->name.'自动打卡失败, 打卡平台服务器异常');
      }
   }

   public function zhjyLogTask($task){
      $user = DawnZhjyUser::where('dawn_id', $task->user_id)->first();
      $loginBody = [
               "appLogin"=>"true",
               "loginAccount"=> $user->dawn_zhjyUser,
               "password"=> $user->dawn_zhjyPassword,
               "appUserId"=>"",
               "loginUserType"=>$user->dawn_zhjyidEntity,
               "enrollmentYear"=>$user->dawn_zhjyEnrollmentYear
         ];
     $response = Http::withHeaders($this->headers)->post($this->apiUrl->getLoginUrl(), $loginBody);
     if ($response->successful()) {
         // 获取响应的 JSON 数据
         $message = $response->json();
         if($message['code'] == 500){
            throw new BusinessException($task->name.'智慧教育,用户名或密码不正确');
         }
         $data = $response->json()['data'];
          // 获取实习Id
          $token = 'Bearer '.$data['token'];
          $userId = $data['userId'];
          $nickName = $data['nickName'];
          $autonomyPlanId = $this->zhjyService->getStudentPlanId($token);
          Log::info('获取实习Id:');
          Log::info($autonomyPlanId);
         /**
          * 获取自动打卡的任务配置、打卡图片数量、打卡地址随机开关、打卡反馈开关等配置
          */
          $taskSettings = LogTaskSettings::where('user_id', $task->user_id)->first();
          if($taskSettings){
            $taskSettings = $taskSettings->toArray();
            Log::info($taskSettings);
            $settings_id = $taskSettings['id'];
            $settings_user_id = $taskSettings['user_id'];
            $settings_image_count = $taskSettings['image_count'];
            $settings_default_images = $taskSettings['default_images'];
            $settings_random_log = $taskSettings['random_log'];
            $settings_log_type = Utils::getLogType($taskSettings['log_type']);
            $settings_created_at = $taskSettings['created_at'];
            $settings_updated_at = $taskSettings['updated_at'];
            $settings_deleted_at = $taskSettings['deleted_at'];
            if($settings_random_log == true){
               // 获取随机日志         
               Log::info('获取随机日志');
               if($settings_log_type == '4'){
                  // 获取所有类型的数据
                  $logDetails = ZhjyRepot::where('user_id', $task->user_id)
                  ->inRandomOrder() // 随机获取一条
                  ->where('isdelete', 1)
                  ->first();
               }else{
                  $logDetails = ZhjyRepot::where('user_id', $task->user_id)
                  ->inRandomOrder() // 随机获取一条
                  ->where('isdelete', 1)
                  ->where('recordType', $settings_log_type)
                  ->first();
               }
            }else{
               // 从最旧的日志获取
               Log::info('从最旧的日志获取');
               if($settings_log_type == '4'){
                  // 获取所有类型的数据
                  $logDetails =ZhjyRepot::where('user_id', $task->user_id)
                  ->orderBy('created_at', 'desc')  
                  ->where('isdelete', 1)
                  ->first();
               }else{
                  $logDetails =ZhjyRepot::where('user_id', $task->user_id)
                  ->orderBy('created_at', 'desc')  
                  ->where('isdelete', 1)
                  ->where('recordType', $settings_log_type)
                  ->first();
               }
              
            }
            if(is_null($logDetails)){
               throw new BusinessException($task->name.'没有当前类型'.$taskSettings['log_type'].'的日志');
            }

            // 定义授权头
            $currentHeader = [
               "Authorization" => $token,
            ];

            // 确定上传图片数据量
            if (is_null($logDetails->fileId) || strlen($logDetails->fileId) === 0){
               // 没有图片,再看看有没有开启默认上传图片, 如果都没有的话就不上传
               if($settings_default_images == true){
                  // 确定上传图片数据量
                  $count = DawnOss::where('user_id', $task->user_id)
                        ->where("status", 1)
                        ->get()
                        ->count();
                  if ($count < $settings_image_count){
                     throw new BusinessException($task->name.'智慧教育,没有足够的图片');
                  }
                  $imageids = [];
                  $delHash = [];
                  Log::info('上传图片数量:'.$settings_image_count);
                  for($i = 0; $i < $settings_image_count; $i++){
                     $ossPath = DawnOss::where('user_id', $task->user_id)
                        ->inRandomOrder() // 随机获取一条
                        ->where("status", 1) // 随机获取一条
                        ->first();
                     $path = storage_path('app/public/' . ltrim($ossPath['file_path'], '/'));
                     // $path =asset('storage/' . $ossPath['file_path']);
                     $file = new UploadedFile($path, $ossPath['file_name']);
                     $result = $this->zhjyService->uploadFile($currentHeader, $file);
                     if($result['code'] == 500){
                        Log::error('上传图片失败:'.$result['message']);
                        continue; // 跳过当前循环
                     }
                     $id = $result['id'];
                     $url = $result['url'];
                     $fileName = $result['url'];
                     $imageids[] = $id;
                     $delHash[] = $ossPath['file_hash'];
                     
                  }
                  $fileIdsStr = implode(',', $imageids);
               }else{
                  $fileIdsStr = '';
                  $delHash = []; // 初始化$delHash变量，即使不上传图片
               }
            }else{
               // 如果有自带照片，默认照片就会失效
               $imageids = [];
               $delHash = [];
               $fileIdsStr = $logDetails->fileId;
               $fileIds = explode(',', $fileIdsStr);
               foreach ($fileIds as $fileId) {
                  $ossPath = DawnOss::where('file_hash', $fileId)
                                       ->where("status", 1)
                                       ->first();
                  
                  if (is_null($ossPath)) {
                     Log::error('无法找到文件哈希为 ' . $fileId . ' 的图片记录');
                     continue; // 跳过当前循环
                  }
                  
                  $path = storage_path('app/public/' . ltrim($ossPath['file_path'], '/'));
                  // $path =asset('storage/' . $ossPath['file_path']);
                  $file = new UploadedFile($path, $ossPath['file_name']);
                  $result = $this->zhjyService->uploadFile($currentHeader, $file);
                  if($result['code'] == 500){
                     Log::error('上传图片失败:'.$result['message']);
                     continue; // 跳过当前循环
                  }
                  $id = $result['id'];
                  $url = $result['url'];
                  $fileName = $result['url'];
                  $imageids[] = $id;
                  $delHash[] = $ossPath['file_hash'];
               }
               $fileIdsStr = implode(',', $imageids);
            }
            
            $logBody = [
               'recordType' => $logDetails->recordType, // 日志类型
               'recordTime' => Utils::getFormatted_datetime_now(), // 日志时间
               'todaySummary' =>  $logDetails->todaySummary, // 今日总结
               'nextSummary' => $logDetails->nextSummary, // 下周计划
               'feedback' => $logDetails->feedback, // 反馈
               'selfEvaluate' => $logDetails->selfEvaluate, // 自评
               'userId' => $userId, // 用户id
               'nickName' => $nickName, // 姓名
               'fileId' => $fileIdsStr, // 文件id
               'autonomyId' => $autonomyPlanId, // 实习id
           ];
           $mergedHeaders = array_merge($this->headers, $currentHeader);

            $response = Http::withHeaders($mergedHeaders)
                  ->post($this->apiUrl->getLogUrl(), $logBody);

            $data = $response->json();
            $push = Push::where('user_id', $task->user_id)->first();
            if($data['code'] == 500){
               if(!is_null($push)){
                  $sendMsg = [
                     "token"=> $push->token,
                     "msg"=> $data['msg'] ?? "实习日志提交失败",
                 ];
                  $this->pushService->sendMsg($sendMsg);
               }
               throw new BusinessException($task->name.'智慧教育,日志提交失败');
            }
            if($data['code'] == 200){
               Log::info('日志提交成功');
               if(!is_null($push)){
                  $sendMsg = [
                     "token"=> $push->token,
                     "msg"=> '实习日志提交成功-'."1日报 2周报 3月报,当前日志类型: ".$logBody['recordType'].'时间: '.Utils::getFormatted_datetime_now(),
                 ];
                  $this->pushService->sendMsg($sendMsg);
               }
               foreach ($delHash as $hash) {
                  DawnOss::where('file_hash', $hash)->update(['status' => 0]);
                  Log::info('删除图片:'.$hash);
               }
            }
            Log::info($data); 
            
          }else{
            throw new BusinessException($task->name.'智慧教育,请先配置打卡设置');
          }
          Log::info('获取日志上报设置模版');

      } else {

         throw new BusinessException($task->name.'自动上传日志失败, 打卡平台服务器异常');
      }
   }



}
